function [bFound, DataPath, DataFile, StFile] = searchDataByParam(Path, StFilePattern, DataFilePattern, varargin)

%%
hFunc = @(x) x;
for i = 1 : length(varargin)
    if i == 1 && isa(varargin{i}, 'function_handle')
        hFunc = varargin{i};
        continue
    end
    varname = inputname(i+3);
    if isempty(varname)
        error([
            'The %dth Param Name should be defined explicitly! \n'...
            'Or, if you have defined this param, please be sure that any myinput param cannot be in the form of "st.x".'], i);
    end
    
    st.(varname) = varargin{i};
end
st = hFunc(st);

%%
TEMP_DATA = 'USELESS TEMP DATA!';

[ParentPath, SubFolders, FolderPattern] = analyPath(Path);
[DataPath, DataFile, StFile] = search_param(ParentPath, SubFolders, st, StFilePattern, hFunc);
bFound = ~isempty(DataPath);
if bFound
    if isdir(DataFile) || isempty(DataFile) || ~exist(DataFile, 'file'), return; end
    st_file = dir(DataFile);
    if st_file.bytes > 250, return; end
    
    data = importdata(DataFile);
    if ischar(data) && strcmp(data, TEMP_DATA)
        bFound = false;
    end
    return
end

DataPath = getNewFileName(ParentPath, FolderPattern, @isdir, @mkdir);
StFile = getNewFileName(DataPath, StFilePattern, @(x)exist(x, 'file'));

if ~isempty(DataFilePattern)
    [~, ~, ext] = fileparts(DataFilePattern);
    if isempty(ext)
        DataFile = getNewFileName(DataPath, DataFilePattern, @isdir, @mkdir);
    else
        DataFile = getNewFileName(DataPath, DataFilePattern, @(x)exist(x, 'file'));
        save(DataFile, 'TEMP_DATA');
    end
    [~, data_file, ext] = fileparts(DataFile);
    st.related_data_file = [data_file, ext];
end

save(StFile, 'st');

function [ParentPath, SubFolders, FolderPattern] = analyPath(Path)
if strcmp(Path(end), filesep)
    Path(end) = [];
end

[ParentPath, FolderPattern] = fileparts(Path);
bFolderPattern = ~isempty(strfind(FolderPattern, '*'));
if ~bFolderPattern
    FolderPattern = '';
    ParentPath = Path;
    SubFolders = {''};
else
    SubFolders = dir(Path);
    SubFolders = {SubFolders(:).name};
end

function NewFile = getNewFileName(Path, Pattern, hExist, hMake)
if nargin < 4, hMake = @(x)[]; end

if isempty(strfind(Pattern, '*'))
    NewFile = fullfile(Path, Pattern);
    if ~isdir(Path), mkdir(Path); end
    if ~isempty(Pattern), hMake(NewFile); end
    return
end

k = length(dir(fullfile(Path, Pattern)));
while true
    k = k + 1;
    NewFile = fullfile(Path, strrep(Pattern, '*', num2str(k)));
    if ~hExist(NewFile), break; end
end
hMake(NewFile);

function [DataPath, DataFile, StFile] = search_param(Path, SubFolders, st, StFilePattern, hFunc)
st = hFunc(st);
DataPath = '';  DataFile = '';  StFile = '';
for i = 1 : length(SubFolders)
    SubPath = fullfile(Path, SubFolders{i});
    if ~isdir(SubPath), continue; end
    stFiles = dir(fullfile(SubPath, StFilePattern));
    for j = 1 : length(stFiles)
        StFile = fullfile(SubPath, stFiles(j).name);
        st0 = importdata(StFile);
        if isfield(st0, 'related_data_file')
            DataFile = st0.related_data_file;
            st0 = rmfield(st0, 'related_data_file');
        end
        if isequal(hFunc(st0), st)
            DataPath = SubPath;
            if ~isempty(DataFile)
                DataFile = fullfile(DataPath, DataFile);
            end
            return
        end
    end
end
